import os
import re
import sqlite3
from datetime import datetime

from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware

# 硬编码基础目录路径
BASE_DIR = "/data/minecraft/paper-1.20.4-parkour-hielke/plugins/qwq-spigot-plugin/scoreboard_loggings"

# AuthMe 数据库文件路径
AUTHME_DB_PATH = "/data/minecraft/paper-1.21.8-lobby/server/plugins/AuthMe/authme.db"

# 初始化 FastAPI 应用
app = FastAPI(
    title="Scoreboard API",
    description="Minecraft 服务器计分板数据接口",
    version="0.1.0-alpha1"
)

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 预定义过滤规则
uuid_pattern = re.compile(r'^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$', re.IGNORECASE)
excluded_players = {
    "rank_s", "rank_a", "rank_b", "rank_c", "CONSOLE", "minute", "hour",
}

@app.get("/qwq_scoreboard/{scoreboard_name}")
async def get_scoreboard(scoreboard_name: str):
    """
    获取指定计分板数据
    """
    try:
        # 构建完整文件路径
        file_path = os.path.join(BASE_DIR, scoreboard_name, f"{scoreboard_name}_logging.txt")
        
        # 验证文件存在性
        if not os.path.isfile(file_path):
            raise HTTPException(status_code=404, detail="Scoreboard file not found")

        # 读取文件内容
        with open(file_path, 'r', encoding='utf-8') as f:
            lines = f.readlines()

        # 解析数据
        parsed_data = []
        last_update = None

        for line in lines:
            line = line.strip()
            
            # 跳过空行
            if not line:
                continue
            
            # 解析时间戳（首行）
            if not last_update:
                try:
                    last_update = datetime.fromtimestamp(
                        int(line) / 1000
                    ).isoformat()
                except ValueError:
                    raise HTTPException(
                        status_code=500,
                        detail="Invalid timestamp format in file"
                    )
                continue

            # 过滤 UUID 行
            if uuid_pattern.match(line.split(':', 1)[0].strip()):
                continue

            # 解析玩家数据
            parts = line.split(':')
            if len(parts) != 2:
                continue

            name_part, score_part = parts
            name = name_part.strip()
            
            # 过滤指定玩家
            if name in excluded_players:
                continue

            # 解析分数
            try:
                score = int(score_part.strip())
            except ValueError:
                continue

            parsed_data.append({
                "name": name,
                "score": score
            })

        return {
            "last_update_time": last_update,
            "scoreboard_data": parsed_data
        }

    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"Internal server error: {str(e)}"
        )
        
@app.get("/qwq_scoreboard_list")
async def get_scoreboard_list():
    """
    获取所有计分板的名字
    """
    try:
        scoreboard_names = [
            d for d in os.listdir(BASE_DIR)
            if os.path.isdir(os.path.join(BASE_DIR, d))
        ]

        return {"scoreboard_name_list": scoreboard_names}

    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"Internal server error: {str(e)}"
        )

@app.get("/qwq_authme_data")
async def get_authme_data():
    """
    获取 AuthMe 数据库中玩家的注册和登录信息。
    """
    conn = None
    try:
        # 检查数据库文件是否存在
        if not os.path.isfile(AUTHME_DB_PATH):
            raise HTTPException(status_code=404, detail="AuthMe database file not found")
        
        # 连接到 SQLite 数据库
        conn = sqlite3.connect(AUTHME_DB_PATH)
        conn.row_factory = sqlite3.Row  # 使得查询结果可以按字段名访问
        cursor = conn.cursor()

        # 执行查询
        query = "SELECT realname, ip, regip, lastlogin, regdate FROM authme"
        cursor.execute(query)
        rows = cursor.fetchall()

        # 格式化数据
        result_list = []
        for row in rows:
            result_list.append({
                "realname": row["realname"],
                "ip": row["ip"],
                "regip": row["regip"],
                "lastlogin": row["lastlogin"],
                "regdate": row["regdate"]
            })

        return result_list

    except sqlite3.OperationalError as e:
        # 特别处理权限问题或文件锁定问题
        raise HTTPException(
            status_code=500,
            detail=f"Database operational error: {str(e)}. Please check file permissions and NFS settings."
        )

    except Exception as e:
        # 捕获其他所有异常
        raise HTTPException(
            status_code=500,
            detail=f"Internal server error: {str(e)}"
        )
    finally:
        # 确保连接在任何情况下都会被关闭
        if conn:
            conn.close()

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8326, reload=True)